﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Web.Mvc;
using Xenta.Attributes;
using Xenta.Utils;
using Xenta.Web.Controllers;

namespace Xenta.Web.Areas.Wizard.Controllers
{
    [Authenticate]
    public sealed class ForumTopicController : ExtController
    {
        [HttpGet, RestoreState]
        public ActionResult Create(int forumID)
        {
            dynamic m = new ExpandoObject();

            m.Topic = null;
            m.Forum = Svc.ProcessOperation("GetForum", new
            {
                EntityID = forumID
            }, new
            {
                DisclosureLevel = "Entire",
                DisclosureOptions = new Dictionary<String, String>
                {
                    { "TranslatedTo", JDM.String(Svc.Localization.Language.Code) }
                }.Unload()
            });
            if(m.Forum == null)
                return HttpNotFound();

            var acl = m.Forum.AccessRules as IEnumerable<dynamic>;
            if(acl.Any())
            {
                var tmp = acl.Where(x => Svc.InRole((string)JDM.String(x.Role.Code)))
                    .Select(x => JDM.String(x.AccessRights));
                if(!tmp.Any(x => x.Contains("Moderate") || x.Contains("ReadWrite")))
                    return new HttpUnauthorizedResult();
            }
            return View(m);
        }

        [HttpPost, PersistState, ValidateInput(false)]
        public ActionResult Create(int forumID, string title, string description)
        {
            try
            {
                var m = Svc.ProcessOperation("CreateForumTopic", new
                {
                    MemberID = JDM.Int32(Svc.ForumMember.EntityID),
                    ForumID = forumID,
                    Title = title,
                    Description = description,
                    Flags = "Active"
                });
                return RedirectToAction(Loc.Act("Show").Ctrl("Topic").Area("Forum").Set(new
                {
                    id = JDM.Int32(m.EntityID)
                }).Localized());
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }

            return RedirectToAction(Loc.Act("Create").Set(new
            {
                forumID
            }).Localized());
        }

        [HttpGet, RestoreState]
        public ActionResult Edit(int id)
        {
            dynamic m = new ExpandoObject();

            m.Topic = Svc.ProcessOperation("GetForumTopic", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Entire"
            });
            if(m.Topic == null)
                return HttpNotFound();

            m.Forum = Svc.ProcessOperation("GetForum", new
            {
                EntityID = JDM.Int32(m.Topic.Forum.EntityID)
            }, new
            {
                DisclosureLevel = "Entire",
                DisclosureOptions = new Dictionary<String, String>
                {
                    { "TranslatedTo", JDM.String(Svc.Localization.Language.Code) }
                }.Unload()
            });

            var acl = m.Forum.AccessRules as IEnumerable<dynamic>;
            m.UserCanModerate = acl.Where(x => Svc.InRole((string)JDM.String(x.Role.Code)))
                .Any(x => JDM.String(x.AccessRights).Contains("Moderate"));
            if(JDM.Int32(m.Topic.Member.EntityID) != JDM.Int32(Svc.ForumMember.EntityID) && 
                !m.UserCanModerate)
            {
                return new HttpUnauthorizedResult();
            }
            if(m.UserCanModerate)
            {
                m.AvailableForums = Svc.ProcessOperation("SearchForums", new
                {
                    SortBy = new[] 
                    {
                        "DisplayOrder"
                    }
                }, new
                {
                    DisclosureLevel = "Base"
                }).Items;
            }
            return View(m);
        }

        [HttpPost, PersistState, ValidateInput(false)]
        public ActionResult Update(int id, string title, string description)
        {
            var topic = Svc.ProcessOperation("GetForumTopic", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Base"
            });
            if(topic == null)
                return HttpNotFound();

            try
            {
                Svc.ProcessOperation("UpdateForumTopic", new
                {
                    EntityID = id,
                    ForumID = JDM.Int32(topic.Forum.EntityID),
                    Title = title,
                    Description = description,
                    Flags = JDM.String(topic.Flags)
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(ModelState.IsValid
                ? Loc.Act("Show").Ctrl("Topic").Area("Forum").Set(new
                {
                    id
                }).Localized()
                : Loc.Act("Edit").Set(new
                {
                    id
                }).Localized());
        }

        [HttpPost, PersistState, ValidateInput(false)]
        public ActionResult Moderate(int id, int forumID, string title, string description, string[] flags)
        {
            var topic = Svc.ProcessOperation("GetForumTopic", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Base"
            });
            if(topic == null)
                return HttpNotFound();

            var forum = Svc.ProcessOperation("GetForum", new
            {
                EntityID = JDM.Int32(topic.Forum.EntityID)
            }, new
            {
                DisclosureLevel = "Entire",
                DisclosureOptions = new Dictionary<String, String>
                {
                    { "TranslatedTo", JDM.String(Svc.Localization.Language.Code) }
                }.Unload()
            });

            var acl = forum.AccessRules as IEnumerable<dynamic>;
            if(!acl.Where(x => Svc.InRole((string)JDM.String(x.Role.Code)))
                .Any(x => JDM.String(x.AccessRights).Contains("Moderate")))
            {
                return new HttpUnauthorizedResult();
            }

            try
            {
                Svc.ProcessOperation("UpdateForumTopic", new
                {
                    EntityID = id,
                    ForumID = forumID,
                    Title = title,
                    Description = description,
                    Flags = flags.Merge(",")
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(ModelState.IsValid
                ? Loc.Act("Show").Ctrl("Topic").Area("Forum").Set(new
                {
                    id
                }).Localized()
                : Loc.Act("Edit").Set(new
                {
                    id
                }).Localized());
        }

        [HttpGet, PersistState]
        public ActionResult Delete(int id)
        {
            try
            {
                Svc.ProcessOperation("DeleteForumTopic", new
                {
                    EntityID = id
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }

            return RedirectToAction(ModelState.IsValid
                ? Loc.Act("Index").Ctrl("Forum").Area("Forum").Localized()
                : Loc.Act("Edit").Set(new
                {
                    id
                }).Localized());
        }
    }
}
